using System;
using Microsoft.Xna.Framework;

namespace SolarWinds.Helpers
{
    /// <summary>
    /// Static methods to assist with random-number generation.
    /// </summary>
    public static class RandomHelper
    {
        #region Random Singleton

        /// <summary>
        /// The Random object used for all of the random calls.
        /// </summary>
        private static readonly Random sRandom = new Random();
        public static Random Random
        {
            get { return sRandom; }
        }

        #endregion


        #region Single Variations

        /// <summary>
        /// Generate a random floating-point value between the minimum and 
        /// maximum values provided.
        /// </summary>
        /// <remarks>This is similar to the Random.Next method, substituting singles
        /// for integers.</remarks>
        /// <param name="minimum">The minimum value.</param>
        /// <param name="maximum">The maximum value.</param>
        /// <returns>A random floating-point value between the minimum and maximum v
        /// alues provided.</returns>
        public static float RandomBetween(float minimum, float maximum)
        {
            return minimum + (float)sRandom.NextDouble() * (maximum - minimum);
        }


        #endregion


        #region Direction Generation

        /// <summary>
        /// Generate a random direction vector.
        /// </summary>
        /// <returns>A random direction vector in 2D space.</returns>
        public static Vector2 RandomDirection()
        {
            float angle = RandomBetween(0, MathHelper.TwoPi);
            return new Vector2((float)Math.Cos(angle),
                               (float)Math.Sin(angle));
        }


        /// <summary>
        /// Generate a random direction vector within constraints.
        /// </summary>
        /// <param name="minimumAngle">The minimum angle.</param>
        /// <param name="maximumAngle">The maximum angle.</param>
        /// <returns>
        /// A random direction vector in 2D space, within the constraints.
        /// </returns>
        public static Vector2 RandomDirection(float minimumAngle, float maximumAngle)
        {
            float angle = RandomBetween(MathHelper.ToRadians(minimumAngle),
                                        MathHelper.ToRadians(maximumAngle)) - MathHelper.PiOver2;
            return new Vector2((float)Math.Cos(angle),
                               (float)Math.Sin(angle));
        }

        #endregion


        /// <summary>
        /// Genrates random Vector3 with each component between -0.5 and 0.5
        /// </summary>
        public static Vector3 RandomVector3()
        {
            var randVector3 = new Vector3((float)sRandom.NextDouble(),
                                          (float)sRandom.NextDouble(),
                                          (float)sRandom.NextDouble());

            randVector3 -= Vector3.One * 0.5f;

            randVector3.Normalize();

            return randVector3;
        }

        /// <summary>
        /// Genrates random float between 0 and 1
        /// </summary>
        public static float RandomFloat()
        {
            return (float)sRandom.NextDouble();
        }

        /// <summary>
        /// Genrates random float between -1 and 1
        /// </summary>
        public static float RandomFloat2()
        {
            return (((float)sRandom.NextDouble()) - 0.5f) * 2.0f;
        }
    }
}